package com.anrongtec.zcpt.utils;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import com.anrongtec.zcpt.JWTApp;
import com.anrongtec.zcpt.db.LiteOrmDBUtil;
import com.anrongtec.zcpt.model.AppModel;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;


/**
 * 
 * @ClassName: Util
 * @Description: 工具类
 * @author dongtianhao
 * @date 2016年7月8日 下午3:29:56
 *
 */
public class Util extends IUtil {

	private static final String TAG = "Util";

	public static void post(Runnable r) {
		new Thread(r).start();
	}

	public static void post(Activity act, Runnable r) {
		act.runOnUiThread(r);
	}

	/**
	 * 获取从市场下载的apps 判断条件是: 数据库保存的包名
	 * 
	 * @return
	 */
	public static List<AppModel> getAppsFromMaket(Context context) {

		List<AppModel> apps = new ArrayList<AppModel>();
		AppModel tempApp = null;

		// 获取包列表
		List<AppModel> queryAll = LiteOrmDBUtil.getQueryAll(AppModel.class);
		if (Util.isEmpty(queryAll)) {
			return apps;
		}

		List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(0);
		for (PackageInfo packageInfo : packages) {
			// 是否是系统应用
			if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {

				for (AppModel appModel : queryAll) {
					// 符合包名,且不为应用包名
					if (packageInfo.packageName.equals(appModel.getAppPackName())
							&& !packageInfo.packageName.equals(getPackageName(context))) {
						// OK
						tempApp = new AppModel();
						tempApp.setAppName(
								packageInfo.applicationInfo.loadLabel(context.getPackageManager()).toString());
						tempApp.setLocalIcon(packageInfo.applicationInfo.loadIcon(context.getPackageManager()));
						tempApp.setLocalVersionName(packageInfo.versionName);
						tempApp.setLocalVersionCode(packageInfo.versionCode);
						tempApp.setAppPackName(packageInfo.packageName);
						tempApp.setSize(new File(packageInfo.applicationInfo.sourceDir).length());
						tempApp.setFirstInstallTime(packageInfo.firstInstallTime);
						tempApp.setLastUpdateTime(packageInfo.lastUpdateTime);
						LogUtil.trace(Log.DEBUG, "Util", tempApp.getAppName());

						apps.add(tempApp);// 如果非系统应用，则添加至appList
					}
				}

			}
		}

		return apps;
	}

	/**
	 * 获取非系统应用
	 */
	/*
	 * public static List<AppModel> getAppsInfo(Context context) {
	 * 
	 * List<AppModel> apps = new ArrayList<AppModel>(); AppModel tempApp = null;
	 * 
	 * List<PackageInfo> packages = context.getPackageManager()
	 * .getInstalledPackages(0); for (PackageInfo packageInfo : packages) {
	 * //是否是系统应用 if ((packageInfo.applicationInfo.flags &
	 * ApplicationInfo.FLAG_SYSTEM) == 0) { tempApp = new AppModel();
	 * tempApp.setAppName(packageInfo.applicationInfo.loadLabel(
	 * context.getPackageManager()).toString());
	 * tempApp.setLocalIcon(packageInfo.applicationInfo.loadIcon(context
	 * .getPackageManager()));
	 * tempApp.setLocalVersionName(packageInfo.versionName);
	 * tempApp.setLocalVersionCode(packageInfo.versionCode);
	 * tempApp.setAppPackName(packageInfo.packageName); tempApp.setSize(new
	 * File(packageInfo.applicationInfo.sourceDir) .length());
	 * tempApp.setFirstInstallTime(packageInfo.firstInstallTime);
	 * tempApp.setLastUpdateTime(packageInfo.lastUpdateTime);
	 * LogUtil.trace(Log.DEBUG, "Util", tempApp.getAppName()); //排除商店应用本身 if
	 * (tempApp.getAppPackName().equals(getPackageName(context))) { continue; }
	 * apps.add(tempApp);// 如果非系统应用，则添加至appList } }
	 * 
	 * return apps; }
	 */

	public static AppModel getAppInfoByPkg(Context context, String pkg) {
		AppModel app = new AppModel();
		try {
			PackageInfo packageInfo = context.getPackageManager().getPackageInfo(pkg, 0);
			app.setAppName(packageInfo.applicationInfo.loadLabel(context.getPackageManager()).toString());
			app.setLocalIcon(packageInfo.applicationInfo.loadIcon(context.getPackageManager()));// 图标
			app.setLocalVersionName(packageInfo.versionName);// 本地版本名
			app.setLocalVersionCode(packageInfo.versionCode);// 本地版本号
			app.setAppPackName(packageInfo.packageName);// 包名
			app.setSize(new File(packageInfo.applicationInfo.sourceDir).length());// 本地大小
			app.setFirstInstallTime(packageInfo.firstInstallTime);// 第一次安装时间
			app.setLastUpdateTime(packageInfo.lastUpdateTime);// 最后一次升级时间

			return app;

		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}

		return app;
	}
	public static AppModel getAppInfoFromDB(String pkg){
		return LiteOrmDBUtil.getInfoById(pkg, AppModel.class);
	}


	/**
	 * 获取当前的UTC时间
	 * 
	 * @return
	 */
	public static String getCurrentUTCTime() {
		// MyLogcat.log(new
		// SimpleDateFormat("yyyyMMddHHmmss").format(trans2UTC(new Date())));
		// return new SimpleDateFormat("yyyyMMddHHmmss").format(trans2UTC(new
		// Date()));
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
		LogUtil.trace(Log.DEBUG, TAG, sdf.format(new Date()));
		return sdf.format(new Date());
	}

	/**
	 * date转为UTC date
	 * 
	 * @param date
	 * @return
	 */
	public static Date trans2UTC(Date date) {
		java.util.Calendar cal = java.util.Calendar.getInstance();

		int zoneOffset = cal.get(java.util.Calendar.ZONE_OFFSET);

		int dstOffset = cal.get(java.util.Calendar.DST_OFFSET);
		cal.setTime(date);

		cal.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset));
		return cal.getTime();
	}

	/**
	 * 获取IMEI
	 */
	public static String getImei(Context context) {
		TelephonyManager mTelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		return mTelephonyMgr.getDeviceId();
		// mTelephonyMgr.getLine1Number();//获取电话号码
	}

	/**
	 * 获取IMSI
	 */
	public static String getImsi(Context context) {
		TelephonyManager mTelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		return mTelephonyMgr.getSubscriberId();
	}

	/**
	 * 获取设备序列号
	 * 
	 * @return
	 */
	public static String getDeviceSN(Context context) {
		return Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
	}

	/**
	 * 获取版本名称 versionName例如1.0
	 * 
	 * @return
	 */
	public static String getVersionName(Context c) {
		String versionName = "";
		try {
			PackageManager pm = c.getPackageManager();
			PackageInfo pi = pm.getPackageInfo(c.getPackageName(), 0);
			versionName = pi.versionName;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return versionName;
	}

	/**
	 * 获取版本编号 versionCode 例如1
	 * 
	 * @return
	 */
	public static int getVersionCode(Context c) {
		int versionCode = 0;
		try {
			PackageManager pm = c.getPackageManager();
			PackageInfo pi = pm.getPackageInfo(c.getPackageName(), 0);
			versionCode = pi.versionCode;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return versionCode;
	}

	public static String getPackageName(Context c) {
		return c.getPackageName();
	}

	/**
	 * 获取mac
	 * 
	 * @param c
	 * @return
	 */
	public static String getMac(Context c) {

		String macAddress = null;
		WifiManager wifiMgr = (WifiManager) c.getSystemService(Context.WIFI_SERVICE);
		WifiInfo info = (null == wifiMgr ? null : wifiMgr.getConnectionInfo());
		if (null != info) {
			macAddress = info.getMacAddress();
		}
		return macAddress;
	}

	/**
	 * 获取ip
	 * 
	 * @param c
	 * @return
	 */
	public static String getIP(Context c) {
		// WiFi未连接的情况下，无法获取IP
		String ip = null;
		WifiManager wifiMgr = (WifiManager) c.getSystemService(Context.WIFI_SERVICE);
		WifiInfo info = (null == wifiMgr ? null : wifiMgr.getConnectionInfo());
		if (null != info) {
			ip = int2ip(info.getIpAddress());
		}
		return ip;
	}

	/**
	 * ip转换
	 * 
	 * @param ipInt
	 * @return
	 */
	public static String int2ip(long ipInt) {
		StringBuilder sb = new StringBuilder();
		sb.append(ipInt & 0xFF).append(".");
		sb.append((ipInt >> 8) & 0xFF).append(".");
		sb.append((ipInt >> 16) & 0xFF).append(".");
		sb.append((ipInt >> 24) & 0xFF);
		return sb.toString();
	}

	/**
	 * 获取AppOS 例如: H30-L01M:4.4.2
	 * 
	 * @return
	 */
	public static String getAppOS() {
		return Build.MODEL + ":" + Build.VERSION.RELEASE;
	}

	// 这个是获取SHA1的方法
	public static String getCertificateSHA1Fingerprint(Context context) {
		// 获取包管理器
		PackageManager pm = context.getPackageManager();
		// 获取当前要获取SHA1值的包名，也可以用其他的包名，但需要注意，
		// 在用其他包名的前提是，此方法传递的参数Context应该是对应包的上下文。
		String packageName = context.getPackageName();
		// 返回包括在包中的签名信息
		int flags = PackageManager.GET_SIGNATURES;
		PackageInfo packageInfo = null;
		try {
			// 获得包的所有内容信息类
			packageInfo = pm.getPackageInfo(packageName, flags);
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		// 签名信息
		Signature[] signatures = packageInfo.signatures;
		byte[] cert = signatures[0].toByteArray();
		// 将签名转换为字节数组流
		InputStream input = new ByteArrayInputStream(cert);
		// 证书工厂类，这个类实现了出厂合格证算法的功能
		CertificateFactory cf = null;
		try {
			cf = CertificateFactory.getInstance("X509");
		} catch (CertificateException e) {
			e.printStackTrace();
		}
		// X509证书，X.509是一种非常通用的证书格式
		X509Certificate c = null;
		try {
			c = (X509Certificate) cf.generateCertificate(input);
		} catch (CertificateException e) {
			e.printStackTrace();
		}
		String hexString = null;
		try {
			// 加密算法的类，这里的参数可以使MD4,MD5等加密算法
			MessageDigest md = MessageDigest.getInstance("SHA1");
			// 获得公钥
			byte[] publicKey = md.digest(c.getEncoded());
			// 字节到十六进制的格式转换
			hexString = byte2HexFormatted(publicKey);
		} catch (NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (CertificateEncodingException e) {
			e.printStackTrace();
		}
		return hexString;
	}

	// 这里是将获取到得编码进行16进制转换
	private static String byte2HexFormatted(byte[] arr) {
		StringBuilder str = new StringBuilder(arr.length * 2);
		for (int i = 0; i < arr.length; i++) {
			String h = Integer.toHexString(arr[i]);
			int l = h.length();
			if (l == 1)
				h = "0" + h;
			if (l > 2)
				h = h.substring(l - 2, l);
			str.append(h.toUpperCase());
			if (i < (arr.length - 1))
				str.append(':');
		}
		return str.toString();
	}

	/**
	 * apk大小 由byte转为M
	 * 
	 * @param l
	 * @return
	 */
	public static String byte2Mega(long l) {

		double d = l / 1024d / 1024d;

		return new DecimalFormat("0.00").format(d) + "M";

	}

	/**
	 * 判断集合是否为null 或者 无数据
	 * 
	 * @param <T>
	 * @return
	 */
	public static <T> boolean isEmpty(Collection<T> c) {
		if (c == null) {
			return true;
		}
		if (c.isEmpty()) {
			return true;
		}
		return false;
	}

	/**
	 * 拼接下载apk的url
	 */
	public static String getDownloadUrl(String url) {
		Map<String, String> map = JWTApp.getInstance().getBaseInfo();
		return url + "&imei=" + map.get("imei") + "&imsi=" + map.get("imsi") + "&uuid=" + map.get("uuid") + "&baseInfo="
				+ JWTApp.getInstance().getBaseInfoJson();
	}

	public static String getIp() {
		try {
			for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
				NetworkInterface intf = en.nextElement();
				for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
					InetAddress inetAddress = enumIpAddr.nextElement();
					if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
						return inetAddress.getHostAddress();
					}
				}
			}
		} catch (SocketException ex) {
			ex.printStackTrace();
		}
		return null;
	}

	/**
	 * Get IP address from first non-localhost interface
	 * 
	 * @param useIPv4
	 *            true=return ipv4, false=return ipv6
	 * @return address or empty string
	 *//*
		 * public static String getIPAddress(boolean useIPv4) { try {
		 * List<NetworkInterface> interfaces =
		 * Collections.list(NetworkInterface.getNetworkInterfaces()); for
		 * (NetworkInterface intf : interfaces) { List<InetAddress> addrs =
		 * Collections.list(intf.getInetAddresses()); for (InetAddress addr :
		 * addrs) { if (!addr.isLoopbackAddress()) { String sAddr =
		 * addr.getHostAddress().toUpperCase(); boolean isIPv4 =
		 * InetAddressUtils.isIPv4Address(sAddr); if (useIPv4) { if (isIPv4)
		 * return sAddr; } else { if (!isIPv4) { int delim = sAddr.indexOf('%');
		 * // drop ip6 port suffix return delim < 0 ? sAddr : sAddr.substring(0,
		 * delim); } } } } } } catch (Exception ex) { } return ""; }
		 */

	/**
	 * 返回当前的应用是否处于前台显示状态
	 * 
	 * @return
	 */
	public static boolean isForeground(Context context, String className) {
		if (context == null || TextUtils.isEmpty(className)) {
			return false;
		}

		ActivityManager am = (ActivityManager) context.getApplicationContext()
				.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningAppProcessInfo> list = am.getRunningAppProcesses();
		if (list.size() == 0) {
			return false;
		}
		for (RunningAppProcessInfo process : list) {

		}

		return false;
	}
	
	/**
	 * 判断是否有网
	 * 
	 * @param context
	 * @return
	 */
	public static boolean isNetworkAvailable(Context context) {
		ConnectivityManager connectivity = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (connectivity == null) {
			Log.i("NetWorkState", "Unavailabel");
			return false;
		} else {
			NetworkInfo[] info = connectivity.getAllNetworkInfo();
			if (info != null) {
				for (int i = 0; i < info.length; i++) {
					if (info[i].getState() == NetworkInfo.State.CONNECTED) {
						Log.i("NetWorkState", "Availabel");
						return true;
					}
				}
			}
		}
		return false;
	}
}
